

import Router from '@koa/router';
import db from '../mysqlHelper.js';
import logger from '../logger.js';
import response from '../response.js';
import moment from 'moment';
import md5 from 'md5';
import axios from 'axios';
import redis from '../redis.js';



const router = new Router();
router.prefix('/api');

router.post('/oprtation/startChargee', async (ctx) => {
    let body = ctx.request.body;
    if (body == null) {
        ctx.body = response.fail('参数不允许为空');
        return;
    }
    if (body.sn == null) {
        ctx.body = response.fail('缺少必填字段 sn');
        return;
    }
    if (body.station_name == null) {
        ctx.body = response.fail('缺少必填字段 充电桩名称');
        return;
    }
    if (body.project_id == null) {
        ctx.body = response.fail('缺少必填字段 项目id');
        return;
    }
    if (body.isp_id == null) {
        ctx.body = response.fail('缺少必填字段 服务商id');
        return;
    }
    if (body.path == null) {
        ctx.body = response.fail('缺少必填字段 服务商路径');
        return;
    }
    if (body.phone == null) {
        ctx.body = response.fail('缺少必填字段 车主电话');
        return;
    }
    if (body.openid == null) {
        ctx.body = response.fail('缺少必填字段 车主openid');
        return;
    }
    if (body.guns_no == null) {
        ctx.body = response.fail('缺少必填字段 枪号');
        return;
    }
    if (body.balance == null) {
        ctx.body = response.fail('缺少必填字段 余额');
        return;
    }
    let billing_rules_id = 0;
    let billing_rules_name = '';
    let billing_rules_value = {};
    /*收费规则数量*/
    let billing_rules_number = 0;
    //查询默认的收费标准
    let sql = `select * from billing_rules where project_id='${body.project_id}' and type=0`;
    let rules = await db.query(sql);
    if (rules instanceof Error) {
        logger.error(`获取默认收费标准失败 error :` + rules.message, `project_id:${body.project_id}`);
        ctx.body = response.fail('获取默认收费标准失败');
        return;
    }
    billing_rules_number = rules.length;
    if (rules.length == 0) {
        ctx.body = response.fail('该项目没有配置四轮车充电收费规则，请联系管理员配置后重试');
        return;
    } else if (rules.length == 1) {
        billing_rules_id = rules[0].id;
        billing_rules_name = rules[0].name;
        billing_rules_value.electricityRate = rules[0].rules_value.electricityRate;
        billing_rules_value.serviceRate = rules[0].rules_value.serviceRate;
        billing_rules_value.billingIndex = rules[0].rules_value.billingIndex;
        billing_rules_value.jsbl = rules[0].rules_value.jsbl;

    } else {
        //如果有多个收费标准 取默认的收费标准
        let default_rule = rules.find(item => item.is_default == 1);
        if (default_rule) {
            billing_rules_id = default_rule.id;
            billing_rules_name = default_rule.name;
            billing_rules_value.electricityRate = default_rule.rules_value.electricityRate;
            billing_rules_value.serviceRate = default_rule.rules_value.serviceRate;
            billing_rules_value.billingIndex = default_rule.rules_value.billingIndex;
            billing_rules_value.jsbl = default_rule.rules_value.jsbl;
        } else {
            ctx.body = response.fail('该项目存在多个四轮车充电收费规则,请联系管理员配置默认收费规则后重试');
            return;
        }
    }


    //查询是否为注册车辆并更新对应的收费规则
    if (body.plate != null && body.plate != '') {
        //查询车号是否为注册车辆
        sql = `select start_time,end_time,type,billing_rules_id from vehicle where plate='${body.plate}'and project_id='${body.project_id}'`;
        let result = await db.query(sql);
        if (result instanceof Error) {
            logger.error(`获取车号信息失败 error :` + result.message, `plate:${body.plate}`);
            ctx.body = response.fail('查询车辆信息出现错误');
            return;
        }
        //对比车辆的开始时间和结束时间是否在当前时间内
        if (result.length > 0) {
            let start_time = moment(result[0].start_time);
            let end_time = moment(result[0].end_time);
            let now_time = moment()
            if (now_time < start_time || now_time > end_time) {
                console.warn(`${body.plate} 车辆不在有效期内,按临时车处理`);
            }
            else {
                if (result[0].type == 1) {
                    //免费车  计费规则为-1 
                    billing_rules_id = -1;
                    billing_rules_name = '免费车';
                    billing_rules_value.electricityRate = new Array(4).fill(0)
                    billing_rules_value.serviceRate = new Array(4).fill(0);
                    billing_rules_value.billingIndex = new Array(48).fill(1)
                    billing_rules_value.jsbl = 0;
                } else {
                    //内部车或者储值车按车辆绑定的收费标准计费
                    billing_rules_id = result[0].billing_rules_id;
                    let billing_rules = await db.findOne('billing_rules', { id: billing_rules_id });
                    billing_rules_name = billing_rules.name;
                    billing_rules_value.electricityRate = billing_rules.rules_value.electricityRate;
                    billing_rules_value.serviceRate = billing_rules.rules_value.serviceRate;
                    billing_rules_value.billingIndex = billing_rules.rules_value.billingIndex;
                    billing_rules_value.jsbl = billing_rules.rules_value.lossRate;
                }

            }
        }
    }
    let tradeNo = '';
    if (body.tradeNo != null && body.tradeNo != '') {
        //如果传入了tradeNo 说明是临时车 直接使用传入的tradeNo
        tradeNo = body.tradeNo;
    } else {
        tradeNo = moment().format('YYMMDDHHmmss') + Math.floor(Math.random() * 10000).toString().padStart(4, '0');
    }

    //开始创建充电订单表
    let chargeing_order = {
        id: tradeNo,
        sn: body.sn,
        station_name: body.station_name,
        rules_name: billing_rules_name,
        path: body.path,
        isp_id: body.isp_id,
        project_id: body.project_id,
        phone: body.phone,
        openid: body.openid,
        start_time: moment().format('YYYY-MM-DD HH:mm:ss'),
        guns_no: body.guns_no,
        start_type: 0,
        electricity_rate: JSON.stringify(billing_rules_value.electricityRate)
    }
    if (body.plate != null && body.plate != '') {
        chargeing_order.plate = body.plate;
    }
    if (body.vin != null && body.vin != '') {
        chargeing_order.vin = body.vin;
    }
    let ip = await redis.getChargeStationInfo(body.sn);
    if (ip == null) {
        ctx.body = response.fail('充电桩不在线');
        return;
    }



    let res = await db.create('chargeing_order', chargeing_order);
    if (res instanceof Error) {
        logger.error(`创建充电订单失败 error :` + res.message, `charging_order:${JSON.stringify(chargeing_order)}`);
        ctx.body = response.fail('创建充电订单失败');
        return;
    }
    let request_data = {
        sn: body.sn,
        tradeNo: tradeNo,
        rules_value: billing_rules_value,
        gunNo: body.guns_no,
        balance: body.balance,
        billing_rules_number: billing_rules_number,
    }
    console.log('请求数据', JSON.stringify(request_data));

    let url = `http://${ip}:82/api/device/startCharge`;
    res = await request_device_server(url, request_data, '启动充电');
    console.log('硬件服务器返回', JSON.stringify(res));
    if (res instanceof Error) {
        ctx.body = response.fail(`请求启动充电失败 ${res.message}`);
        return;
    }
    if (res.code != 0) {
        ctx.body = response.fail(`请求启动充电失败 ${res.msg}`);
        let delete_sql = `delete from chargeing_order where id='${tradeNo}'`;
        console.log(`删除充电订单 sql :` + delete_sql);
        let delete_res = await db.query(delete_sql);
        if (delete_res instanceof Error) {
            logger.error(`删除充电订单失败 error :` + delete_res.message, `charging_order:${JSON.stringify(chargeing_order)}`);
            ctx.body = response.fail('删除充电订单失败');
            return;
        }
        ctx.body = response.fail(`请求启动充电失败`, res.data);
        return;

    }
    if (res.data.status == 0)//充电桩返回充电失败 删除订单
    {
        let delete_sql = `delete from chargeing_order where id='${tradeNo}'`;
        console.log(`删除充电订单 sql :` + delete_sql);
        let delete_res = await db.query(delete_sql);
        if (delete_res instanceof Error) {
            logger.error(`删除充电订单失败 error :` + delete_res.message, `charging_order:${JSON.stringify(chargeing_order)}`);
            ctx.body = response.fail('删除充电订单失败');
            return;
        }
        ctx.body = response.fail(`请求启动充电失败`, res.data);
        return;
    }
    let response_data = res.data;
    response_data.tradeNo = tradeNo;
    ctx.body = response.success(response_data);

});

async function request_device_server(url, request_data, method_name) {
    try {
        let res = await axios.post(url, request_data, {
            headers: {
                'Content-Type': 'application/json',
                'Accept': 'application/json'
            }
        });
        console.log(`向硬件服务器发送${method_name}请求 url:${url} ,请求参数:${JSON.stringify(request_data)} 返回数据:${JSON.stringify(res.data)}`);
        return res.data;
    } catch (error) {
        console.error(`向硬件服务器发送${method_name}请求失败 url:${url} ,请求参数:${JSON.stringify(request_data)} 错误内容:${error.message}`);
        return error;
    }

}

router.post('/oprtation/stopChargee', async (ctx) => {
    let body = ctx.request.body;
    if (body == null) {
        ctx.body = response.fail('参数不允许为空');
        return;
    }
    if (body.sn == null) {
        ctx.body = response.fail('缺少必填字段 sn');
        return;
    }
    if (body.guns_no == null) {
        ctx.body = response.fail('缺少必填字段 枪号');
        return;
    }
    let ip = await redis.getChargeStationInfo(body.sn);
    if (ip == null) {
        ctx.body = response.fail('充电桩不在线');
        return;
    }
    let request_data = {
        sn: body.sn,
        gunNo: body.guns_no,
    }
    if (body.tradeNo != null && body.tradeNo != '') {
        request_data.tradeNo = body.tradeNo;
    }
    let url = `http://${ip}:82/api/device/stopCharge`;
    let res = await request_device_server(url, request_data, '停止充电');
    if (res instanceof Error) {
        ctx.body = response.fail(`请求停止充电失败 ${res.message}`);
        return;
    }
    if (res.code != 0) {
        ctx.body = response.fail(`请求停止充电失败 ${res.msg}`);
        return;
    }
    ctx.body = response.success(res.data);
});

router.post('/oprtation/setQRCode', async (ctx) => {
    let body = ctx.request.body;
    if (body == null) {
        ctx.body = response.fail('参数不允许为空');
        return;
    }
    if (body.qrCode == null) {
        ctx.body = response.fail('缺少必填字段 qrCode');
        return;
    }
    if (body.sn == null) {
        ctx.body = response.fail('缺少必填字段 sn');
        return;
    }
    let ip = await redis.getChargeStationInfo(body.sn);
    if (ip == null) {
        ctx.body = response.fail('充电桩不在线');
        return;
    }
    let request_data = {
        sn: body.sn,
        qrCode: body.qrCode,
    }
    let url = `http://${ip}:82/api/device/setQRCode`;
    let res = await request_device_server(url, request_data, '设置二维码');
    if (res instanceof Error) {
        ctx.body = response.fail(`请求设置二维码失败 ${res.message}`);
        return;
    }
    if (res.code != 0) {
        ctx.body = response.fail(`请求设置二维码失败 ${res.message}`);
        return
    }
    ctx.body = response.success();
});

//远程重启充电桩
router.post('/oprtation/reboot', async (ctx) => {
    let body = ctx.request.body;
    if (body == null) {
        ctx.body = response.fail('参数不允许为空');
        return;
    }
    if (body.sn == null) {
        ctx.body = response.fail('缺少必填字段 sn');
        return;
    }
    let ip = await redis.getChargeStationInfo(body.sn);
    if (ip == null) {
        ctx.body = response.fail('充电桩不在线');
        return;
    }
    let request_data = {
        sn: body.sn,
    }
    let url = `http://${ip}:82/api/device/reboot`;
    let res = await request_device_server(url, request_data, '重启充电桩');
    if (res instanceof Error) {
        ctx.body = response.fail(`请求重启充电桩失败 ${res.message}`);
        return;
    }
    if (res.code != 0) {
        ctx.body = response.fail(`请求重启充电桩失败 ${res.message}`);
        return;
    }
    ctx.body = response.success();
});

//开始下载收费规则到充电桩


router.post('/operation/camera/reboot', async (ctx) => {
    let body = ctx.request.body;
    if (body == null) {
        ctx.body = response.fail('参数不允许为空');
        return;
    }
    if (body.sn == null) {
        ctx.body = response.fail('缺少必填字段 sn');
        return;
    }
    let ip = await redis.getLotCameraInfo(body.sn);
    if (ip == null) {
        ctx.body = response.fail('摄像头不在线');
        return;
    }
    let request_data = {
        sn: body.sn,
    }
    let url = `http://${ip}:82/api/camera/reboot`;
    let res = await request_device_server(url, request_data, '重启摄像头');
    if (res instanceof Error) {
        ctx.body = response.fail(`请求重启摄像头失败 ${res.message}`);
        return;
    }
    if (res.code != 0) {
        ctx.body = response.fail(`请求重启摄像头失败 ${res.message}`);
        return;
    }
    ctx.body = response.success();
});


/**
* 生成16位订单号：YYMMDDHHmmss + 4位随机数
* @returns {string}
*/
function generateOrderNo() {
    const now = moment().format('YYMMDDHHmmss'); // 12位
    const rand = Math.floor(Math.random() * 10000).toString().padStart(4, '0'); // 4位随机数
    console.log('生成的订单号:', now + rand, '长度:', now.length + rand.length);
    return now + rand; // 共16位
}
router.post('/bike/startCharge', async (ctx) => {
    let body = ctx.request.body;
    if (body == null) {
        ctx.body = response.fail('参数不允许为空');
        return;
    }
    if (body.sn == null) {
        ctx.body = response.fail('缺少必填字段 sn');
        return;
    }
    if (body.isStart == null || body.isStart == undefined) {
        ctx.body = response.fail('缺少必填字段 isStart');
        return;
    }
    // let charge = redis.getBikeChargeStationInfo(body.sn);
    // if (charge == undefined) {
    //     console.log('充电桩不在线', sn);
    //     ctx.body = response.fail('充电桩不在线');
    //     return;
    // }
    let station = await db.findOne('bike_station', { sn: body.sn });
    if (station == null) {
        ctx.body = response.fail('充电桩不存在');
        return;
    }
    let orderNo = '';
    let chargeing_order = null
    if (body.isStart == 1) {
        orderNo = generateOrderNo();
        chargeing_order = {
            id: orderNo,
            sn: body.sn,
            station_name: station.name,
            rules_name: body.rules_name,
            path: station.path,
            isp_id: station.isp_id,
            project_id: station.project_id,
            phone: body.phone,
            openid: body.openid,
            start_time: moment().format('YYYY-MM-DD HH:mm:ss'),
            port_no: body.portNo,
            start_type: 0
        }
    }
    console.log('生成的订单号:', orderNo);


    let ip = await redis.getBikeChargeStationInfo(body.sn);
    if (ip == null) {
        ctx.body = response.fail('充电桩不在线');
        return;
    }
    body.orderNo = orderNo;

    console.log('请求数据', JSON.stringify(body));
    let url = `http://${ip}:82/api/bike/startCharge`;
    let res = await request_device_server(url, body, '启动充电');
    console.log('硬件服务器返回', JSON.stringify(res));
    if (res instanceof Error) {
        ctx.body = response.fail(`二轮启动充电出错 ${res.message}`);
        return;
    }
    if (res.code != 0) {
        ctx.body = response.fail(`二轮请求启动充电失败 ${res.msg}`);
        return;

    } else {
        if (body.isStart == 1) {
            let res = await db.create('bike_chargeing_order', chargeing_order);
            if (res instanceof Error) {
                logger.error(`创建充电订单失败 error :` + res.message, `charging_order:${JSON.stringify(chargeing_order)}`);
                ctx.body = response.fail('创建充电订单失败');
                return;
            }
        }
        let response_data = res.data;
        ctx.body = response.success(response_data);
        return;
    }




});



export { router };